#include "ChatBox.h"
#include "Config.h"
#include "DeviceManager.h"

using namespace Ogre;

template<> ChatBox* Singleton<ChatBox>::ms_Singleton = 0;

ChatBox::ChatBox()
{
	mTextTime = 5.0f;
	fadeOn = true;
	bufferTime = Config::TEXTTIME;
}

void ChatBox::setPosition(Ogre::Real leftRel, Ogre::Real topRel)
{
	// Positions should be relative to screen
	unsigned int width, height, depth;
	int left, top;
	Ogre::Root::getSingletonPtr()->getAutoCreatedWindow()->getMetrics(width, height, depth, left, top);
	mPanel->setPosition(static_cast<Ogre::Real>(leftRel*width), static_cast<Ogre::Real>(topRel*height));
}

void ChatBox::setDimensions(Ogre::Real widthRel, Ogre::Real heightRel)
{
	unsigned int width, height, depth;
	int left, top;
	Ogre::Root::getSingletonPtr()->getAutoCreatedWindow()->getMetrics(width, height, depth, left, top);
	mPanel->setDimensions(static_cast<Ogre::Real>(widthRel*width), static_cast<Ogre::Real>(heightRel*height));
}

void ChatBox::init()
{
	// Setting variables
	numRows = 3;
	mTextBox.resize(numRows, 0);
	mDisplayTime.resize(numRows, 0.0f);

	mOverlay = OverlayManager::getSingleton().create("ChatBoxOverlay");

	mPanel = static_cast<OverlayContainer*>(OverlayManager::getSingleton().createOverlayElement("Panel", "container1"));
	mPanel->setMetricsMode(GMM_PIXELS);
	setDimensions(Config::CHATBOX_WIDTH, Config::CHATBOX_HEIGHT);
	setPosition(Config::CHATBOX_LEFTPOS, Config::CHATBOX_TOPPOS);

	unsigned int width, height, depth;
	int left, top;
	Ogre::Root::getSingletonPtr()->getAutoCreatedWindow()->getMetrics(width, height, depth, left, top);
	
	// now create the text...
	String name;
	for (unsigned int i = 0; i < numRows; ++i)
	{
		name = "ChatBoxRow"+StringConverter::toString(i);
		mTextBox[i] = OverlayManager::getSingleton().createOverlayElement("TextArea", name);
		mTextBox[i]->setMetricsMode(Ogre::GMM_PIXELS);
		mTextBox[i]->setDimensions(20, 5);		
		mTextBox[i]->setWidth(20);
		mTextBox[i]->setHeight(5);

		mTextBox[i]->setPosition(POSITION_TOP_X, POSITION_TOP_Y+i*SPACING);
		mTextBox[i]->setParameter("font_name", "StarWars");
		if (width >= 1072)
			mTextBox[i]->setParameter("char_height", "13");
		else
			mTextBox[i]->setParameter("char_height", "12");
		mTextBox[i]->setColour(ColourValue::White);
		mTextBox[i]->setCaption(" ");
		mPanel->addChild(mTextBox[i]);
	}

	mOverlay->add2D(mPanel);
	mOverlay->show();
}

void ChatBox::addText(const String& text) 
{
	// first swap the content...
	for (unsigned int i = 0; i < numRows-1; ++i)
	{
		mTextBox[i]->setCaption(mTextBox[i+1]->getCaption());
		mDisplayTime[i] = mDisplayTime[i+1];
	}
	mTextBox[numRows-1]->setCaption(text);
	mDisplayTime[numRows-1] = mTextTime;
}

void ChatBox::addToBuffer(const String& text) 
{
	autoBuffer.push(text);
}

void ChatBox::loop(Real time) 
{
	if (bufferTime > 0.0f)
		bufferTime -= time;

	if (fadeOn)
	{
		for (unsigned int i=0; i<numRows; ++i)
		{
			if (mDisplayTime[i] > 0)
				mDisplayTime[i] -= time;
			else
			{
				mDisplayTime[i] = 0.0f;
				mTextBox[i]->setCaption(" ");
			}
			mTextBox[i]->setColour(ColourValue(1,1,1,mDisplayTime[i]/mTextTime));
		}
	}
	// If buffer is not empty, and time is ripe, flush to screen
	if (!autoBuffer.empty() && bufferTime <=0.0f)
	{
		Ogre::String temp = autoBuffer.front();
		autoBuffer.pop();
		addText(temp);
		bufferTime = Config::TEXTTIME;
	}
}

void ChatBox::clear() 
{
	for (unsigned int i=0; i<numRows; i++)
	{
		mTextBox[i]->setCaption(" ");
		mDisplayTime[i] = mTextTime;
		mTextBox[i]->setColour(ColourValue::White);
	}
	while (!autoBuffer.empty())
		autoBuffer.pop();
	fadeOn = true;
}

void ChatBox::setFadeOn(bool on)
{
	fadeOn = on;
}

/*void ChatBox::shutdown()
{
	Ogre::OverlayContainer* mPanel;
	Ogre::Overlay* mOverlay;
	std::vector<Ogre::OverlayElement*> mTextBox;
	std::vector<Ogre::Real> mDisplayTime;
	unsigned int numRows;
	Ogre::Real mTextTime;
	bool fadeOn;
}*/